Skip to content

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Sep 10, 2025

The layout(std430) cbuffer syntax was not working correctly in .slang files, causing incorrect ArrayStride values in generated SPIR-V. Arrays of int2 were getting ArrayStride 16 (std140 layout) instead of ArrayStride 8 (std430 layout).

The issue occurred because the parseHLSLCBufferDecl function only processed GLSL layout qualifiers when allowGLSLInput was enabled, but layout parsing itself is always available. This meant that while layout(std430) was parsed and attached as a modifier, it was ignored during cbuffer processing in .slang files.

Before:

OpDecorate %_arr_v2int_int_2 ArrayStride 16  // Wrong - using std140
OpName %SLANG_ParameterGroup_CBlock_std140 "SLANG_ParameterGroup_CBlock_std140"

After:

OpDecorate %_arr_v2int_int_2 ArrayStride 8   // Correct - using std430
OpName %SLANG_ParameterGroup_CBlock_std430 "SLANG_ParameterGroup_CBlock_std430"

This fix ensures that layout(std430) cbuffer declarations work consistently whether using .slang or .glsl files, and that the generated SPIR-V uses the correct layout rules for buffer members.

Additionally, the compiler now emits warnings when GLSL layout qualifiers (std140, std430, scalar) are used with non-Khronos targets (e.g., DXIL, HLSL, Metal), helping users identify potential compatibility issues without breaking existing code.

Fixes #8373.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@Copilot Copilot AI changed the title [WIP] [SPIRV] wrong ArrayStride inside layout(std430) cbuffer Fix std430 layout support for cbuffers in .slang files Sep 11, 2025
@Copilot Copilot AI requested a review from bmillsNV September 11, 2025 00:06
Copilot finished work on behalf of bmillsNV September 11, 2025 00:06
@davli-nv
Copy link
Contributor

Copilot, I think it needs to warn when layout (std430) etc are used when compiling for other targets (warn instead of error to make it a non-breaking PR), and accept these layout modifiers when compiling for GLSL/SPIRV without requiring -allow-glsl

// Check for GLSL layout qualifiers when GLSL input is allowed
if (parser->options.allowGLSLInput && parser->pendingModifiers)
// Check for GLSL layout qualifiers (layout modifiers can be used even without allowGLSLInput)
if (parser->pendingModifiers)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot, I think it needs to warn when layout (std430) etc are used when compiling for other targets (warn instead of error to make it a non-breaking PR), and accept these layout modifiers when compiling for GLSL/SPIRV without requiring -allow-glsl

int2 a[2];
};

ConstantBuffer<B, Std430DataLayout> c;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot, for simplicity this ConstantBuffer can be dropped

@davli-nv davli-nv self-assigned this Sep 25, 2025
@davli-nv
Copy link
Contributor

@claude can you update this PR based on review comments, or make new PR if needed

Copy link
Contributor

github-actions bot commented Sep 30, 2025

Claude finished @davli-nv's task —— View job


I've successfully updated the PR based on the review comments! ✅

Todo List:

  • Analyze current implementation and review comments
  • Understand Slang's target system and warning mechanisms
  • Implement warning system for layout qualifiers on incompatible targets
  • Modify parser to accept layout modifiers for GLSL/SPIRV without -allow-glsl
  • Simplify test file by removing ConstantBuffer as requested
  • Build and test the changes
  • Commit and push updates

Implementation Summary:

Warning system: Added diagnostic ID 39012 that warns when std430, std140, or scalar layout qualifiers are used on incompatible targets (non-Khronos/WGPU). The warning is issued during semantic analysis where target information is available.

Layout modifier acceptance: The existing code already accepts layout modifiers without requiring -allow-glsl flag (as noted in the comment: "layout modifiers can be used even without allowGLSLInput"), so this requirement was already met.

Test simplification: Removed the ConstantBuffer<B, Std430DataLayout> c; line and related usage as requested in the review.

Changes Made:

  • slang-diagnostic-defs.h: Added diagnostic 39012 for layout qualifier warnings
  • slang-check-modifier.cpp: Added warning logic that checks compilation targets and issues warnings for incompatible ones
  • cbuffer-std430-layout.slang: Simplified test by removing ConstantBuffer usage

The implementation ensures that:

  1. Layout qualifiers work correctly on GLSL/SPIRV targets (non-breaking)
  2. Warnings (not errors) are issued for incompatible targets (non-breaking)
  3. Existing functionality is preserved while addressing the review feedback

The changes have been committed and pushed to the PR branch.


…atible targets

- Add diagnostic 39012 for layout qualifiers on unsupported targets
- Implement warning system that checks compilation targets and warns when
  std430/std140/scalar layout qualifiers are used on non-Khronos/WGPU targets
- Simplify test by removing ConstantBuffer usage as requested in review
- Layout qualifiers are already accepted without -allow-glsl flag (existing behavior)

Addresses review comments on PR #8432.

Co-authored-by: davli-nv <[email protected]>
{
String layoutName;

if (as<GLSLStd140Modifier>(layoutMod))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can use existing modifier->keywordName

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in commit 51d89ee. Now using layoutMod->keywordName instead of manual string construction.

if (!isKhronosTarget(target->getTarget()) && !isWGPUTarget(target->getTarget()))
{
String targetName;
switch (target->getTarget())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there existing function to get human string name of targets?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in commit 51d89ee. Now using the existing printDiagnosticArg function to get human-readable target names.

@@ -0,0 +1,15 @@
//TEST:SIMPLE(filecheck=SPIRV): -target spirv -entry main -stage fragment -emit-spirv-directly
Copy link
Contributor

@davli-nv davli-nv Oct 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a second case in same test file that checks for warning with other target

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in commit 51d89ee. Added a second test case that targets DXIL and checks for the warning: warning 39012: layout qualifier 'std430' is not supported for target 'dxil'

@davli-nv
Copy link
Contributor

davli-nv commented Oct 3, 2025

@copilot update this PR based on review comments

@Copilot Copilot AI requested a review from davli-nv October 3, 2025 01:47
Copilot finished work on behalf of davli-nv October 3, 2025 01:47
@davli-nv
Copy link
Contributor

davli-nv commented Oct 3, 2025

@copilot can you show how slang handles layout std430 etc for targeting wgpu?

Copy link
Contributor Author

Copilot AI commented Oct 3, 2025

@copilot can you show how slang handles layout std430 etc for targeting wgpu?

For WGPU targets (WGSL, WGSLSPIRV, WGSLSPIRVAssembly), Slang handles layout qualifiers as follows:

  1. No warnings are issued when using layout(std430) with WGPU targets - the code at line 1686 explicitly exempts WGPU targets: !isWGPUTarget(target->getTarget())

  2. For storage buffers and texture buffers: WGPU uses std430 layout rules by default (WGSLLayoutRulesFamilyImpl::getShaderStorageBufferRules() and getTextureBufferRules() return kStd430LayoutRulesImpl_)

  3. For constant buffers (cbuffers): WGPU uses a custom kWGSLConstantBufferLayoutRulesImpl_ which is based on std140 layout rules (line 2291-2292 in slang-type-layout.cpp)

  4. Layout capabilities: The Std430DataLayout type is marked with [require(spirv)] and [require(glsl)] in hlsl.meta.slang, so explicit std430 layout is only available when targeting SPIRV/GLSL, not pure WGSL. However, WGPU targets that go through SPIRV (like WGSLSPIRV) can use the layout qualifiers.

Copilot finished work on behalf of davli-nv October 3, 2025 03:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[SPIRV] wrong ArrayStride inside layout(std430) cbuffer
3 participants